home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 002 / cp2.arc / CP2.ASM next >
Encoding:
Assembly Source File  |  1986-02-12  |  23.5 KB  |  872 lines

  1.       PAGE 55,132
  2.       TITLE CUTPASTE 2.0
  3. ; CUTPASTE -
  4. ;PARAMETERS -- MOST OF THESE MAY BE CHANGED TO ANY DESIRED VALUE
  5.  
  6. wndw_ht    equ 25             ;the size of the screen
  7. wndw_wd    equ 80
  8. cut_key    equ  07000H        ;scan code - ascii of cut (Alt-F9)
  9. paste_key  equ  06600H        ;scan code - ascii of paste (Cntrl-F9)
  10.                 ;now scan codes of edit keys
  11. up_arrow   equ  4800H
  12. down_arrow equ  5000H
  13. left_arrow equ  4B00H
  14. right_arrow equ 4D00H
  15. del_left   equ  0008H         ;user rubout (^H) key
  16. delete     equ  5300H         ;use del (lower right)
  17. insert     equ  5200H
  18. cr         equ  000DH
  19. home       equ  4700H
  20. escape     equ  001BH
  21. tab        equ  7400H         ; ^right arrow
  22. rev_tab    equ  7300H         ; ^left arrow
  23. line_ins   equ  5100H         ;pg down
  24. line_del   equ  4900H         ;pg up
  25. mark_char  equ  4F00H         ;end key
  26.  
  27. blank      equ  00720H       ;define the character which is a blank
  28. attrib     equ  007H         ;and our default attribute (should agree with blank)
  29. video      equ  10H          ;video BIOS call
  30. inv_attrib equ  070H         ;inverse of 'attrib'
  31.     PAGE
  32. CSEG  SEGMENT PARA PUBLIC 'CODE'
  33.       ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:NOTHING   ;STANDARD DECL FOR .COM FILE
  34.  
  35.       ORG  100H
  36.  
  37. Start:
  38.       JMP INSTALL
  39.  
  40. ;PLACE DATA AREA HERE FOR READIBILITY
  41.  
  42. COPYRITE    DB 'Copyright Gerry Boyd, Larry Weiss, Randy Davis 1985  All Rights Reserved'
  43.         DB '(214)238-9545'
  44. SCREENSAVE: DW (WNDW_HT * (WNDW_WD+1)) DUP (BLANK);RESERVE SPACE TO SAVE OPENED WINDOW
  45. LINESAVE:   DW WNDW_WD DUP (BLANK) ;BUFFER FOR LINE DELETE
  46.  
  47. CURSOR_POS  DW 0
  48. OLD_CUR_POS DW 0
  49. SAVESTACK   DW 0,0
  50.  
  51. REQUEST     DW 0              ;REQUEST TYPE
  52.  
  53. KEY_RQST_HANDLER DD 0         ;ADDRESS OF THE ORIGINAL KEYBOARD REQUEST HANDLER
  54.  
  55. LEFT_MARG  DB   00            ;define the confines of the window
  56. RIGHT_MARG DB   00
  57. TOP_MARG   DB   00
  58. BOT_MARG   DB   00
  59. UPPER_LEFT DW   00
  60.  
  61. MARK       DW   -1            ;FLAGS USED IN CHARACTER FEED
  62. FEED_START DW   00            ;ADDRESS IN BUFFER OF BEGIN...
  63. FEED_STOP  DW   00            ;...AND END OF FEED
  64. FEED_END1  DW   00            ;TEMP HOLDING SPOT FOR BEG FEED ADDR
  65. FEED_END2  DW   00            ;TEMP HOLDING SPOT FOR END FEED ADDR
  66.  
  67. FEED_CHAR  DW   00            ;CHAR TO FEED ON THIS CALL
  68.  
  69. DISPLAY_SEG DW 00             ;SAVE OFF THE DISPLAY SEGMENT ***
  70. PAGE
  71. BEGIN PROC FAR                ;FAR LABEL SINCE ITS ENTERED BY INTERRUPT
  72. MAINLOOP:
  73.       MOV  CS:REQUEST,AX      ;SAVE HIS AX REGISTER
  74.  
  75.       MOV  AX,CS:FEED_START   ;ARE WE IN THE MIDDLE OF FEEDING CHARS...
  76.       CMP  AX,CS:FEED_STOP    ;...TO THE APPLICATION?
  77.       JZ   NOFEED             ;NO
  78.       JMP  FEED               ;YES
  79. NOFEED:
  80.       MOV  AX,CS:REQUEST      ;RESTORE USERS AX
  81.       PUSHF                   ;CALL OLD INTERRUPT HANDLER (EMULATE INT INSTRUCTION)
  82.       CALL DWORD PTR [CS:KEY_RQST_HANDLER] ;GO AHEAD AND GET THE CHARACTER
  83.       PUSHF                   ;SAVE THE FLAG RETURNED (FOR AH = 1 REQUESTS)
  84.  
  85.       CMP CS:BYTE PTR REQUEST+1,00H ;WE ARE ONLY INTERESTED IN CHAR. REQUESTS
  86.       JZ  CNTINUE
  87.       JMP FORGET_IT
  88.  
  89. CNTINUE:                      ;YES -- CHECK CHARACTER FOR 'OURS'
  90.       POPF                    ;FOR NON-TYPE 1 REQUESTS DONT NEED TO SAVE FLAGS
  91.       CMP AX,CUT_KEY
  92.       JZ  CNT_AGIN
  93.       CMP AX,PASTE_KEY
  94.       JZ  PASTE_CHAR
  95.  
  96.       JMP RETURN_CHAR
  97.  
  98. CNT_AGIN:                     ;WE GOT IT! GO INTO EDITOR MODE
  99.       MOV CS:SAVESTACK,SP
  100.       MOV CS:SAVESTACK+2,SS
  101.       MOV  AX,CS
  102.       MOV  SS,AX
  103.       MOV  SP,100H
  104.  
  105.       STI                     ;ENABLE INTERRUPTS WHILE PROCESSING CHARACTERS
  106.  
  107.       PUSH BP                 ;SET UP A STACK FRAME
  108.       MOV  BP,SP
  109.       SUB  SP,0EH
  110.       CALL SAVEREG
  111.       MOV  DS,AX
  112.  
  113.       CALL CALC_WINDOW        ;CALCULATE WINDOW EXTREMETIES
  114.  
  115.       CALL READ_CURSOR
  116.       MOV OLD_CUR_POS,DX      ;SAVE THE CURSOR FOR LATER RESTORING
  117.  
  118.       CALL WINDOW_SAVE        ;SAVE SCREEN
  119.  
  120.       MOV DX,CURSOR_POS       ;RESTORE CURSOR IN EDIT WINDOW
  121.       CALL PLACE_CURSOR
  122.  
  123.       CALL EDITOR             ;LET HIM EDIT IN THE WINDOW
  124.  
  125.       CALL READ_CURSOR
  126.       MOV CURSOR_POS,DX       ;SAVE CURSOR IN EDIT WINDOW FOR NEXT EDIT
  127.  
  128.       CALL WINDOW_SWAP        ;PUT BACK WHATEVER WAS ORIGINALLY THERE
  129.  
  130.       MOV DX,OLD_CUR_POS      ;RESTORE THE CURSOR POSITION
  131.       CALL PLACE_CURSOR
  132.  
  133.       CALL RESTREG
  134.       ADD  SP,0EH
  135.       POP  BP
  136.  
  137.       MOV SS,CS:SAVESTACK+2
  138.       MOV SP,CS:SAVESTACK
  139.  
  140.       MOV AH,00              ;RESTORE REQUEST TO SOMETHING DECENT
  141.       JMP MAINLOOP           ;GO GET ANOTHER CHARACTER TO RETURN HIM
  142.  
  143. PASTE_CHAR:
  144.       MOV  AX,CS:FEED_END1   ;BEGIN TO FEED CHARACTER STRING INTO APPLICATION
  145.       MOV  CS:FEED_START,AX
  146.       MOV  AX,CS:FEED_END2
  147.       MOV  CS:FEED_STOP,AX
  148.  
  149.       MOV AH,00              ;RESTORE REQUEST TO SOMETHING DECENT
  150.       JMP MAINLOOP           ;GO GET ANOTHER CHARACTER TO RETURN HIM
  151.  
  152. RETURN_CHAR:
  153.       IRET                   ;RETURN WITH CHARACTER
  154.  
  155. ;HANDLE REQUEST TYPE 1'S BY FAR RETURNING 2 AND TYPE 2'S BY JUST RETURNING
  156.  
  157. FORGET_IT:
  158.       CMP  CS:BYTE PTR REQUEST+1,1      ;was it a "is char present" request?
  159.       JZ   FI100
  160.  
  161.       POPF                   ;no -- just return whatever BIOS returned
  162.       IRET
  163.  
  164. FI100:
  165.       POPF                   ;yes -- make funny return
  166.       RET 02
  167.       PAGE
  168. ;HERE WE ARE IN THE PROCESS OF FEEDING CHARACTERS TO THE APPLICATION
  169. ;FROM THE WINDOW BUFFER (SCREENSAVE)
  170.  
  171. FEED:
  172.       CMP  CS:BYTE PTR REQUEST+1,1       ;WAS THIS A CHAR TYPE REQUEST?
  173.       JA   KSTAT
  174.                 ;YES -- RETURN HIM CHAR
  175.       PUSH BX                 ;GET THE NEXT CHARACTER FROM THE BUFFER
  176.       MOV  BX,AX
  177.       MOV  AX,CS:[BX]
  178.       POP  BX
  179.       XOR  AH,AH              ;WE NO LONGER HAVE THE SCAN CODE, BUT ALL
  180.       MOV  CS:FEED_CHAR,AX    ;ARE ASCII ANYWAY
  181.  
  182.       CMP  CS:BYTE PTR REQUEST+1,0       ;IS THIS A 'GET KEYBOARD CHAR' RQST?
  183.       JNZ  FEED_KEY_STAT
  184.  
  185.       ADD  CS:FEED_START,2    ;YES -- MOVE UP THE POINTER BY 1
  186.  
  187. ;PUT IN SPECIAL CHECK TO SKIP OVER TO BEGINNING OF THE FEED AREA
  188.  
  189.     CMP    AL,CR        ;IS THIS CHARACTER A CARRIAGE RETURN?
  190.     JNZ FEED05
  191.  
  192.     PUSH DX
  193.     MOV    DX,CS:UP_LEFT ;SKIP OVER TO THE BEGINNING
  194.     XOR    DH,DH
  195.     SHL    DX,1        ;IN WORDS
  196.     ADD    CS:FEED_START,DX
  197.     POP    DX
  198. FEED05:
  199.  
  200. ; SKIP ANY TRAILING BLANKS
  201.       PUSH BX
  202.       MOV BX,CS:FEED_START
  203. FEED10:
  204.       CMP BX,CS:FEED_STOP
  205.       JZ  FEED50
  206.       MOV AX,CS:[BX]
  207.       CMP AL,' '
  208.       JZ FEED20
  209.       CMP  AL,00DH
  210.       JNZ FEED50
  211.       MOV CS:FEED_START,BX
  212.       JMP FEED50
  213. FEED20:
  214.       INC BX
  215.       INC BX
  216.       JMP FEED10
  217. FEED50:
  218.       POP BX
  219.  
  220.       MOV AX,CS:FEED_CHAR
  221.     IRET
  222.  
  223. FEED_KEY_STAT:
  224.       STI                     ;NO -- ENABLE INTERRUPTS AND FEED HIM THE
  225.       RET  02                 ;THE Z FLAG CLEAR WITH HIS CHAR
  226.  
  227. KSTAT:
  228.       MOV  AX,CS:REQUEST      ;RESTORE REQUEST TO AH
  229.       PUSHF
  230.       CALL DWORD PTR [CS:KEY_RQST_HANDLER] ;PERFORM BIOS CALL -- WE DON'T KNOW
  231.                 ;WHAT HE'S DOING AND WE SHOULDN'T GET IN THE WAY
  232.       IRET                    ;RETURN THE RESULTS TO HIM (WHATEVER THEY ARE)
  233. BEGIN ENDP
  234.       PAGE
  235. BODY  PROC NEAR               ;MAKE SHORT CALLS ONLY TO THE MAIN ROUTINES
  236. CALC_WINDOW:
  237.       MOV AH,0FH              ;FIND OUT VIDEO MODE FOR CALCULATING WINDOW SIZE
  238.       INT VIDEO               ;GO AHEAD AND GET THE CHARACTER
  239.  
  240. ;***SAVE OFF THE VIDEO SEGMENT***
  241.  
  242.       MOV CX,0B000H           ;IS IT MONOCHROME?
  243.       CMP AL,7                ;WELL LOOK FOR MODE 7
  244.       JZ  CW100
  245.       MOV CX,0B800H           ;NO -- ITS GRAPHIX
  246. CW100:
  247.       MOV DISPLAY_SEG,CX      ;SAVE THIS OFF
  248. ;***
  249.  
  250.       DEC AH                  ;THIS IS THE NUMBER OF COLS ON SCREEN
  251.       MOV RIGHT_MARG,AH       ;SET UP RIGHT AND LEFT MARGINS
  252.       SUB AH,(WNDW_WD - 1)
  253.       MOV LEFT_MARG,AH
  254.  
  255.       MOV TOP_MARG,0          ;WE HAVE NO INFORMATION ON NUMBER OF ROWS
  256.       MOV BOT_MARG,WNDW_HT-1  ;SO WE MUST ASSUME SOMETHING NORMAL (IT ISNT
  257.                   ;AS CRITICAL ANYWAY)
  258.  
  259.       MOV AL,AH               ;NOW ADD UPPER_LEFT HAND CORNER VALUE
  260.       XOR AH,AH
  261.       MOV UPPER_LEFT,AX
  262.  
  263.  
  264.       CMP CURSOR_POS,0        ;IF THIS IS THE FIRST TIME WEVE DONE THIS...
  265.       JNZ CW200
  266.       MOV CURSOR_POS,AX       ;...PLACE THE CURSOR IN THE UPPER LEFT HAND CORNER
  267.  
  268. CW200:
  269.       RET
  270.       PAGE
  271. ;***NEW WINDOW_SWAP PROCEDURE AND WINDOW_SAVE COMBINED -- TWO DIFFERENT
  272. ;ENTRY POINTS TELL WHETHER TO DO THE WRITE OR NOT
  273. ;NOTE THAT THIS PROCEDURE DOES NOT BIOS CALLS -- ALL DIRECT WRITES
  274.  
  275. SWAP_SAVE DB 0
  276.  
  277. WINDOW_SAVE:
  278.       MOV SWAP_SAVE,0         ;MARK THIS ENTRY POINT
  279.       JMP WS025
  280.  
  281. WINDOW_SWAP:
  282.     MOV SWAP_SAVE,0FFH       ;MARK THIS DIFFERENT ENTRY POINT
  283.  
  284. WS025:
  285.     MOV CX,WNDW_HT          ;GET THE NUMBER OF ROWS IN WINDOW AREA
  286.       MOV SI,OFFSET SCREENSAVE;START AT BEGINNING OF BUFFER
  287.       MOV ES,DISPLAY_SEG      ;LOAD UP THE VIDEO SEGMENT
  288.       MOV DI,00
  289.       XOR BX,BX
  290. WS050:
  291.       MOV BL,LEFT_MARG        ;START ON THIS LINE AT THE LEFT MARGIN
  292. WS100:
  293.       SHL  BX,1               ;CHANGE THE COLUMN NUMBER TO BYTE POINTER
  294.       MOV  AX,ES:[BX][DI]     ;GET THE NEXT CHARACTER FROM SCREEN
  295.       XCHG AX,[SI]            ;STORE IT AWAY AND WRITE THE SAVED CHARACTER
  296.       ADD  SI,2               ;AND MOVE SAVE POINTER OVER A WORD
  297. ;***HERE IS THE SWAP SAVE CHECK
  298.       CMP  SWAP_SAVE,0        ;IS THIS WINDOW SWAP OR WINDOW SAVE?
  299.       JZ   WS150
  300.                 ;MUST BE SWAP
  301.       MOV  ES:[BX][DI],AX     ;NOW RESTORE THAT CHARACTER TO THE SCREEN
  302. WS150
  303. ;***
  304.     SHR      BX,1            ;PUT THE BYTE OFFSET BACK TO COLUMN NUMBER
  305.       INC  BX
  306.       CMP  BL,RIGHT_MARG      ;ARE WE BEYOND THE END OF THE LINE?
  307.       JNA  WS100
  308.                   ;YES -- SKIP DOWN TO NEXT LINE
  309.  
  310.       MOV WORD PTR [SI],000DH     ; SO CR'S ARE FED PROPERLY LATER
  311.       INC SI
  312.       INC SI
  313.  
  314.       SHL  BX,1               ;ADJUST DI BY ONE LINE'S WORTH SO THAT IT
  315.       ADD  DI,BX              ;POINTS TO BEGINNING OF NEXT LINE
  316.       LOOP WS050
  317.       RET
  318.       PAGE
  319. EDITOR:
  320.  
  321. ;check for edit keys (such as insert, delete, etc.)
  322. ;if not one of those, assume its ascii and just insert it in the
  323. ;screen return when AltF10 detected.
  324.  
  325. ED100:
  326.       CALL GET_CHAR         ;read a character from the keyboard
  327.       OR   AL,AL            ;if this is ascii then dont retain scan code
  328.       JZ   ED105
  329.       XOR  AH,AH
  330.  
  331. ED105:
  332.     CALL UNSHADE_SCREEN    ;REMOVE PREVIOUS SHADING (IF ANY)
  333.  
  334.       MOV  BX,CURSOR_POS     ;in many cases we need the cursor position
  335.       CMP  AX,CUT_KEY        ;check for exit
  336.       JNZ  ED110
  337.       JMP  ED800
  338.  
  339. ED110:
  340.       CMP  AX,CR             ;check for each special character individually
  341.       JNZ  ED120
  342.       MOV  BL,LEFT_MARG
  343.       INC  BH
  344.       JMP  ED500
  345. ED120:
  346.       CMP  AX,LEFT_ARROW
  347.       JNZ  ED140
  348.       DEC  BL
  349.       JMP  ED500
  350.  
  351. ED140:
  352.       CMP  AX,RIGHT_ARROW
  353.       JNZ  ED160
  354.       INC  BL
  355.       JMP  ED500
  356.  
  357. ED160:
  358.       CMP   AX,UP_ARROW
  359.       JNZ   ED180
  360.       DEC   BH
  361.       JMP   ED500
  362.  
  363. ED180:
  364.       CMP  AX,DOWN_ARROW
  365.       JNZ  ED200
  366.       INC  BH
  367.       JMP  ED500
  368.  
  369. ED200:
  370.       CMP  AX,HOME
  371.       JNZ  ED205
  372.       MOV  BX,UPPER_LEFT
  373.       JMP  ED500
  374.  
  375. ED205:                       ;tab and back tab functions
  376.       CMP  AX,TAB
  377.       JNZ  ED210
  378.       MOV  CL,1              ;go forward
  379.       JMP  ED213
  380.  
  381. ED210:
  382.       CMP  AX,REV_TAB
  383.       JNZ  ED220
  384.  
  385.       MOV  CL,0FFH           ;go backwards one tab slot
  386.       ADD  DL,CL             ;start one char to left initially
  387.  
  388. ED213:
  389.       CALL READ_CHAR         ;get char at current position
  390.       MOV  CH,AL             ;save it for comparison
  391. ED215:
  392.       ADD  DL,CL             ;move over one character
  393.       CMP  DL,RIGHT_MARG     ;stop at left and right margins (or beyond)
  394.       JGE  ED218
  395.       CMP  DL,LEFT_MARG
  396.       JLE  ED218
  397.  
  398.       CALL READ_CHAR         ;read current character
  399.       CMP  CH,' '            ;if original was a space...
  400.       JNZ  ED216
  401.       CMP  AL,' '            ;...then go until not space
  402.       JZ  ED215
  403.       JMP ED217
  404. ED216:
  405.       CMP AL,' '             ;...else, go until space
  406.       JNZ ED215
  407. ED217:
  408.       CMP  CL,0FFH           ;if we were going backwards (towards left)...
  409.       JNZ  ED218
  410.       ADD  DL,1              ;...then scoot back to the right by 1
  411. ED218:
  412.       MOV  BX,DX
  413.       JMP  ED500
  414.  
  415. ED220:
  416.       CMP  AX,ESCAPE         ;wipe out remainder of line
  417.       JNZ  ED240
  418.       MOV  DX,BX
  419.       CALL ERASE_LINE
  420.       JMP  ED500
  421.  
  422. ED240:
  423.       CMP  AX,DEL_LEFT       ;move cursor left one char and then do normal del
  424.       JNZ  ED260
  425.       DEC  BL
  426.       CMP  BL,LEFT_MARG
  427.       JNB  ED250
  428.       MOV  BL,RIGHT_MARG
  429.       CMP  BH,00
  430.       JZ   ED250
  431.       DEC  BH
  432. ED250:
  433.       JMP  ED270
  434.  
  435. ED260:
  436.       CMP  AX,DELETE         ;in delete char we...
  437.       JNZ  ED280
  438. ED270:
  439.       MOV  CL,RIGHT_MARG
  440.       SUB  CL,BL             ;calculate how many chars to right margin
  441.       XOR  CH,CH
  442.       MOV  DX,BX             ;...start at current cursor position...
  443.       JCXZ ED275
  444. ED272:
  445.       INC  DL                ;...get character just to the right...
  446.       CALL READ_CHAR
  447.       DEC  DL                ;...move left one position...
  448.       CALL WRITE_CHAR        ;...and write it there...
  449.       INC  DL                ;...now do it again for the char to the right...
  450.       LOOP ED272             ;...for the distance from cursor to right margin;...
  451. ED275:
  452.       MOV  AX,BLANK
  453.       CALL WRITE_CHAR
  454.       JMP  ED500
  455.  
  456. ED280:
  457.       CMP  AX,INSERT         ;in the case of insert we do reverse of delete
  458.       JNZ  ED300
  459.       MOV  DH,BH             ;start at the right margin
  460.       MOV  DL,RIGHT_MARG
  461.       MOV  CL,DL             ;caculate number of spaces to right
  462.       SUB  CL,BL
  463.       XOR  CH,CH
  464.       JCXZ ED290
  465. ED285:
  466.       DEC  DL
  467.       CALL READ_CHAR
  468.       INC  DL
  469.       CALL WRITE_CHAR
  470.       DEC  DL
  471.       LOOP ED285
  472. ED290:
  473.       MOV  AX,BLANK
  474.       CALL WRITE_CHAR
  475.       JMP  ED500
  476.  
  477. ED300:
  478.       CMP  AX,LINE_INS       ;check for insert line
  479.       JNZ  ED320
  480.       MOV  DH,BOT_MARG       ;we're going to need that
  481. ED305:
  482.       MOV  DL,LEFT_MARG      ;always start at the far left
  483.       CMP  DH,BH             ;are we on our current line?
  484.       JZ   ED315
  485.                  ;no -- then move it down
  486.       MOV  CX,WNDW_WD
  487. ED310:
  488.       DEC  DH
  489.       CALL READ_CHAR         ;get the character
  490.       INC  DH
  491.       CALL WRITE_CHAR        ;and put it back one line higher
  492.       INC  DL                ;move right one character
  493.       LOOP ED310
  494.  
  495.       DEC  DH                ;now move up a line and do it again
  496.       JMP  ED305
  497. ED315:
  498.       MOV  BL,LEFT_MARG      ;move us over the far left marg
  499.       CALL ERASE_LINE        ;and wipe out the line we are on
  500.       JMP  ED500
  501.  
  502. ED320:
  503.       CMP  AX,LINE_DEL       ;and check for line delete
  504.       JNZ  ED340
  505.  
  506. ED325:
  507.       MOV  DL,LEFT_MARG      ;always start at the far left
  508.       CMP  DH,BOT_MARG       ;are we on the last line?
  509.       JZ   ED335
  510.                  ;no -- then move it up
  511.       MOV  CX,WNDW_WD
  512. ED330:
  513.       INC  DH
  514.       CALL READ_CHAR         ;get the character
  515.       DEC  DH
  516.       CALL WRITE_CHAR        ;and put it back one line lower
  517.       INC  DL                ;move right one character
  518.       LOOP ED330
  519.  
  520.       INC  DH                ;now move down a line and do it again
  521.       JMP  ED325
  522. ED335:
  523.       MOV  BL,LEFT_MARG      ;move us over the far left marg of our line
  524.       CALL ERASE_LINE        ;and wipe out the bottom line
  525.       JMP  ED500
  526.  
  527. ED340:
  528.       CMP  AX,MARK_CHAR      ;check for mark
  529.       JNZ  ED400
  530.  
  531.       MOV  DX,BX
  532.       CMP  MARK,-1           ;if mark isnt set...
  533.       JNZ  ED350
  534.       MOV  MARK,BX           ;...just set it and switch its attrib
  535.       CALL READ_CHAR
  536.       MOV  AH,ATTRIB
  537.       CALL WRITE_CHAR
  538.       JMP  ED500
  539.  
  540. ED350:                       ;else, store off feed start and end addresses
  541.       CALL CONVERT_LOC
  542.       MOV  FEED_END1,AX
  543.  
  544.       MOV  DX,MARK
  545.       CALL CONVERT_LOC
  546.       MOV  FEED_END2,AX
  547.  
  548.       MOV  CX,FEED_END1
  549.       CMP  CX,AX
  550.       JNA  ED355
  551.       MOV  FEED_END1,AX
  552.       MOV  FEED_END2,CX
  553. ED355:
  554.     CALL TRIM_SCREEN    ;TRIM OFF UNMARKED THINGS ON SCREEN
  555.       JMP  ED800             ;note that this char exits the note pad
  556.  
  557. ED400:                       ;wasnt an edit character -- must be ascii
  558.                 ;just write the character at current position
  559.       MOV  AH,ATTRIB
  560.       CALL W_CHAR
  561.       INC  BL                ;move over one position
  562.  
  563. ED500:                       ;adjust resulting cursor position
  564.       CMP  BL,RIGHT_MARG
  565.       JLE  ED550
  566.       MOV  BL,RIGHT_MARG
  567. ED550:
  568.       CMP  BH,BOT_MARG
  569.       JLE  ED600
  570.       MOV  BH,BOT_MARG
  571. ED600:
  572.       CMP  BL,LEFT_MARG
  573.       JGE  ED650
  574.       MOV  BL,LEFT_MARG
  575. ED650:
  576.       CMP  BH,TOP_MARG
  577.       JGE  ED700
  578.       MOV  BH,TOP_MARG
  579. ED700:
  580.       MOV  CURSOR_POS,BX
  581.       MOV  DX,BX             ;be sure and move the cursor to the new
  582.       CALL PLACE_CURSOR      ;position
  583.       JMP  ED100
  584.  
  585. ED800:                       ;exit
  586.       RET
  587.       PAGE
  588. ;
  589. ; HERE WE PLACE SOME SMALL GENERAL PURPOSE ROUTINES
  590. ;
  591.  
  592. PLACE_CURSOR:                ;place cursor at location in dx
  593.  
  594.       CALL SHADE_SCREEN       ;if we are in mark mode, set the
  595.                 ;screen square to inverse video
  596.       MOV AH,2H
  597.       PUSH BX
  598.       XOR BX,BX
  599.       INT VIDEO
  600.       POP  BX
  601.       RET
  602.  
  603. UP_LEFT DW 0
  604. LW_RIGHT DW 0
  605. ATTRIBUTE DB 0
  606. SAVE_AX DW 0
  607. SAVE_DX DW 0
  608.  
  609. SHADE_SCREEN:            ;NEW SCREEN SHADING PROCEDURE
  610.     CMP    MARK,-1H    ;IS A MARK SET?
  611.     JZ    SS_END
  612.                 ;YES -- OK SWING INTO ACTION
  613.     MOV    SAVE_AX,AX
  614.     MOV    SAVE_DX,DX
  615.     MOV    ATTRIBUTE,INV_ATTRIB ;FIRST SET THE ATTRIBUTE TO INVERSE
  616.     MOV    BX,CURSOR_POS
  617.         MOV     AX,MARK         ;NOW, CALCULATE THE UPPER LEFT CORNER...
  618.     CMP    BL,AL        ;...OF OUR SHADED BOX
  619.         JA      SS100
  620.     MOV    AL,BL
  621. SS100:
  622.     CMP    BH,AH
  623.     JA    SS200
  624.     MOV    AH,BH
  625. SS200:
  626.     MOV    UP_LEFT,AX
  627.     MOV    AX,MARK ;NOW THE LOWER RIGHT CORNER
  628.     CMP    BL,AL
  629.     JB    SS300
  630.     MOV    AL,BL
  631. SS300:
  632.     CMP    BH,AH
  633.     JB    SS400
  634.     MOV    AH,BH
  635. SS400:
  636.     MOV    LW_RIGHT,AX
  637.     JMP    SS_COMMON
  638.  
  639. UNSHADE_SCREEN:
  640.     CMP    MARK,-1H    ;HERE WE UNSHADE THE SHADED AREA
  641.     JZ    SS_END
  642.     MOV    SAVE_AX,AX
  643.     MOV    SAVE_DX,DX
  644.     MOV    ATTRIBUTE,ATTRIB ;CHANGE THE BOX BACK TO NORMAL
  645.  
  646.  
  647. ;NOW BEGIN TO SHADE IN FROM THE UPPER LEFT TO THE LOWER RIGHT CORNERS
  648.  
  649. SS_COMMON:
  650.     MOV    DX,UP_LEFT
  651.     MOV    BX,LW_RIGHT
  652. SS500:
  653.     CMP    DL,BL            ;ARE WE OFF THE RIGHT END?
  654.     JA    SS600
  655.     MOV    AH,ATTRIBUTE
  656.     CALL    WRITE_ATTRIB
  657.     INC    DL
  658.     JMP    SS500
  659. SS600:
  660.     INC    DH            ;OK WE WENT OFF THE RIGHT END...
  661.     CMP    DH,BH            ;...MOVE DOWN ONE AND CHECK LOWER BOUND
  662.     JA    SS700
  663.     MOV    DL,BYTE PTR UP_LEFT
  664.     JMP    SS500
  665. SS700:
  666.     MOV    AX,SAVE_AX
  667.     MOV    DX,SAVE_DX
  668. SS_END:
  669.     RET
  670.  
  671. TRIM_SCREEN:                ;AFTER HE SELECTS THE SECOND MARK
  672.                     ;WE TRIM OFF THE RIGHT MARG OF SCREEN
  673.     MOV    MARK,-1H        ;FIRST CLEAR MARK
  674.     MOV    BX,UP_LEFT        ;START WITH THE FIRST LINE
  675.     MOV    BL,BYTE PTR LW_RIGHT
  676. TS100:
  677.     MOV    DX,LW_RIGHT        ;COMPARE THIS WITH THE LAST LINE
  678.     CMP    BH,DH            ;FINISHED?
  679.     JZ    TS200
  680.     MOV    DX,BX            ;NO -- ERASE THE END OF THIS LINE
  681.     CALL    ERASE_LINE
  682.     INC    BH            ;AND CONTINUE ON TO NEXT LINE
  683.     JMP    TS100
  684. TS200:
  685.     RET
  686.  
  687. READ_CURSOR:                  ;read cursor location into dx
  688.       MOV AH,3H
  689.       PUSH BX
  690.       XOR BX,BX
  691.       INT VIDEO
  692.       POP  BX
  693.       RET
  694.  
  695. ;***NEW READ CHAR PROCEDURE***
  696. READ_CHAR:                    ;read screen character at location in dx
  697.       CALL CALC_VID_LOC       ;covert the row and column into location
  698.       MOV  AX,ES:[DI]         ;get the character at that location
  699.       RET
  700. ;***
  701.  
  702. R_CHAR:                       ;read screen char at current cursor location
  703.       MOV AH,8H
  704.       PUSH BX
  705.       XOR BH,BH
  706.       INT VIDEO
  707.       POP  BX
  708.       RET
  709.  
  710. ;***NEW WRITE CHAR PROCEDURE
  711. WRITE_CHAR:                   ;write attrib/char in ax at location in dx
  712.       PUSH AX                 ;save the attrib from destruction
  713.       CALL CALC_VID_LOC       ;convert the row and column into location
  714.       POP  AX
  715.       MOV ES:[DI],AX
  716.       RET
  717. WRITE_ATTRIB:
  718.       PUSH AX
  719.       CALL CALC_VID_LOC
  720.       POP  AX
  721.     MOV ES:01[DI],AH
  722.       RET
  723. ;***
  724.  
  725. W_CHAR:                       ;write character at current cursor location
  726.       PUSH BX                 ;save bx register
  727.       MOV  BL,AH
  728.       XOR  BH,BH
  729.       PUSH CX                 ;retain cx register also
  730.       MOV  CX,1
  731.       MOV  AH,9H
  732.       INT VIDEO
  733.       POP  CX
  734.       POP  BX
  735.       RET
  736.  
  737. GET_CHAR:                     ;get character from keyboard into ax
  738.       MOV AH,0H
  739.       PUSHF                   ;simulate call to keyboard handler
  740.       CALL DWORD PTR [KEY_RQST_HANDLER]
  741.       RET
  742.  
  743. ERASE_LINE:                   ;erase the current line from dx to right margin
  744.       MOV  CL,RIGHT_MARG
  745.       SUB  CL,BL
  746.       INC  CL
  747.       XOR  CH,CH
  748.       MOV  SI,OFFSET LINESAVE
  749.  
  750. ER100:
  751.       CALL READ_CHAR         ;get the character @ current location
  752.       MOV  [SI],AX
  753.       ADD  SI,2
  754.  
  755.       MOV  AX,BLANK
  756.       CALL WRITE_CHAR        ;***CHANGED FROM W_CHAR***
  757.       INC  DL
  758.       LOOP ER100
  759.       RET
  760.  
  761. RESTORE_LINE:                ;restore the current line from dx to right margin
  762.       MOV  CL,RIGHT_MARG
  763.       SUB  CL,BL
  764.       INC  CL
  765.       XOR  CH,CH
  766.       MOV  DI,OFFSET LINESAVE
  767.  
  768. RL100:
  769.       MOV  AX,[DI]           ;get the saved char
  770.       CALL WRITE_CHAR         ;put the saved char where indicated
  771.       ADD  DI,2
  772.       INC  DL
  773.       LOOP RL100
  774.       RET
  775.  
  776. CONVERT_LOC:                 ;convert a location on the screen (in dx) into AX
  777.       MOV  CX,DX
  778.       MOV  AX,OFFSET SCREENSAVE
  779. CL100:
  780.       CMP  CH,TOP_MARG
  781.       JZ   CL200
  782.       ADD  AX,(WNDW_WD+1)*2
  783.       DEC  CH
  784.       JMP  CL100
  785.  
  786. CL200:
  787.       CMP  CL,LEFT_MARG
  788.       JZ   CL300
  789.       ADD  AX,2
  790.       DEC  CL
  791.       JMP  CL200
  792.  
  793. CL300:
  794.       RET
  795.  
  796. SAVEREG:
  797.       MOV  -2[BP],BX          ;save reggies on stack frame
  798.       MOV  -4[BP],CX
  799.       MOV  -6[BP],DX
  800.       MOV  -8[BP],SI
  801.       MOV  -0AH[BP],DI
  802.       MOV  -0CH[BP],DS
  803.       MOV  -0EH[BP],ES       ;***ADDED SAVING OF ES***
  804.       RET
  805. RESTREG:
  806.       MOV  BX,-2[BP]          ;NOW PUT THE REGGIES BACK AND PULL DOWN
  807.       MOV  CX,-4[BP]          ;THE STACK FRAME
  808.       MOV  DX,-6[BP]
  809.       MOV  SI,-8[BP]
  810.       MOV  DI,-0AH[BP]
  811.       MOV  DS,-0CH[BP]
  812.       MOV  ES,-0EH[BP]       ;***ADD RESTORE OF ES***
  813.       RET
  814.  
  815. ;***NEW PROCEDURE TO CONVERT ROW AND COLUMN INTO ADDRESS
  816.  
  817. CALC_VID_LOC:                ;convert the row and column in dx into an
  818.                  ;offset into the video display buffer
  819.       XOR  AX,AX
  820.       XOR  DI,DI
  821.       PUSH CX                ;save cx -- some of those who call us need it
  822.       XOR  CX,CX
  823.  
  824.       MOV  AL,RIGHT_MARG     ;get the width of a row
  825.       INC  AX
  826.       MOV  CL,DH             ;put the number of rows into cx
  827.       JCXZ CVL200
  828. CVL100:
  829.       ADD  DI,AX             ;for every row add in another 80/40 columns
  830.       LOOP CVL100
  831. CVL200:
  832.       MOV  AL,DL             ;now move over to the current column
  833.       ADD  DI,AX
  834.  
  835.       POP  CX                ;restore cx
  836.  
  837.       SHL  DI,1              ;now convert this into byte offset
  838.       MOV  ES,DISPLAY_SEG
  839.       RET
  840. ;***
  841.  
  842. BODY  ENDP
  843.       PAGE
  844. INSTALL:
  845. ;THIS PROGRAM INSTALLS THE REST OF THE CODE FOR NOTE PAD
  846.  
  847.       MOV DX,OFFSET MESSAGE  ;OUTPUT 'OK' MESSAGE
  848.       MOV AH,9H
  849.       INT 21H
  850.  
  851.       MOV AX,3516H            ;GET INTERRUPT 16 VECTOR
  852.       INT 21H
  853.       MOV WORD PTR KEY_RQST_HANDLER,BX
  854.       MOV WORD PTR KEY_RQST_HANDLER+2,ES
  855.  
  856.       MOV AX,2516H
  857.       MOV DX,OFFSET BEGIN     ;NOW PUT OUR ROUTINE THERE
  858.       INT 21H
  859.  
  860.       MOV DX,OFFSET INSTALL   ;TERMINATE AND STAY RESIDENT
  861.       ADD DX,100H
  862.       MOV CL,4
  863.       SHR DX,CL
  864.       MOV AH,31H
  865.       INT 21H
  866.  
  867. MESSAGE DB 10,13,'CUTPASTE installed',10,13,' ALT F9 to enable cut    ',
  868.     DB 10,13,'   ^F9 to paste   ',10,13,'$'
  869.  
  870. CSEG ENDS
  871.      END START
  872.